home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 23 / sysact11.zip / SAFMT.PAS < prev    next >
Pascal/Delphi Source File  |  1987-02-02  |  9KB  |  343 lines

  1.  
  2. (*
  3.  * SAFMT  - format system activity report file from
  4.  *          sorted system activity log file captured by SA.
  5.  *
  6.  * Copyright (C) 1987 Samuel H. Smith,
  7.  * all commercial rights reserved.
  8.  *
  9.  * Written by: s.h.smith, 31-jan-87
  10.  *
  11.  *)
  12.  
  13. {$g5120,p5120,c-}
  14.  
  15. const
  16.    version = 'SAFMT v1.1 (2/1/87 SHS)';
  17.  
  18.    copyright: string[80] =
  19.         'Copyright (C) 1987 Samuel H. Smith, all commercial rights reserved.';
  20.  
  21. type
  22.    anystring = string[80];
  23.  
  24.    summary = record
  25.       time:       real;          {total elapsed time}
  26.       runs:       integer;       {count of runs}
  27.       reads:      real;          {count of reads}
  28.       writes:     real;          {count of writes}
  29.       others:     real;          {count of other system calls}
  30.    end;
  31.  
  32.  
  33. var
  34.    line:       anystring;
  35.    name:       anystring;
  36.  
  37.    cmd:        summary;
  38.    other:      summary;
  39.  
  40.    iopt:       boolean;       {-i (exclude i/o counts) option}
  41.    vopt:       boolean;       {-v (exclude headings) option}
  42.    jopt:       boolean;       {-j (combine commands run only once) option}
  43.    sopt:       boolean;       {-s (summary sysact format) option}
  44.  
  45.  
  46. (*
  47.  * log entry format:
  48.  *    0        1         2         3         4         5         6
  49.  *    123456789012345678901234567890123456789012345678901234567890
  50.  *    SYSACT.COM   01-31-87 22:11:44 22:11:44.78 RRRR WWWW OOOO RRRRR
  51.  *    |            |        |        |           |    |    |    |
  52.  *    |            |        |        |           |    |    |    +--runs (dec)
  53.  *    |            |        |        |           |    |    |   (optional)
  54.  *    |            |        |        |           |    |    |
  55.  *    |            |        |        |           |    |    +--misc calls (hex)
  56.  *    |            |        |        |           |    |
  57.  *    |            |        |        |           |    +-------writes (hex)
  58.  *    |            |        |        |           |
  59.  *    |            |        |        |           +------------reads  (hex)
  60.  *    |            |        |        |
  61.  *    |            |        |        +------------------------runtime
  62.  *    |            |        |
  63.  *    |            |        +---------------------------------terminate time
  64.  *    |            |
  65.  *    |            +------------------------------------------terminate date
  66.  *    |
  67.  *    +-------------------------------------------------------filename
  68.  *)
  69.  
  70.  
  71. {extract hex digits from a specified position in the current input line}
  72. function hex(from: integer): real;
  73. const
  74.    digit: array['0'..'F'] of integer =
  75.        (0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15);
  76.    function nibble(fm: integer): real;
  77.    begin
  78.       nibble := int( digit[upcase(line[fm])] shl 4 +
  79.                      digit[upcase(line[fm+1])] );
  80.    end;
  81. begin
  82.    hex := nibble(from) * 256.0 + nibble(from+2);
  83. end;
  84.  
  85.  
  86. {extract the elapsed runtime from the current input line}
  87. function jtime: real;
  88.    function get(from: integer): real;
  89.    begin
  90.       get := int( (ord(line[from]  )-ord('0')) * 10 +
  91.                   (ord(line[from+1])-ord('0')) );
  92.    end;
  93. begin
  94.    jtime := get(32) * 3600.0 +
  95.             get(35) * 60.0 +
  96.             get(38) +
  97.             get(41) / 100.0;
  98. end;
  99.  
  100.  
  101. {update the current cmd totals from the input line}
  102. procedure update_totals;
  103. var
  104.    mult:  real;
  105.    code:  integer;
  106. begin
  107.    if length(line) > 58 then
  108.       val(copy(line,59,5),mult,code)
  109.    else
  110.       mult := 1;
  111.  
  112.    with cmd do
  113.    begin
  114.       time := time + jtime * mult;
  115.       runs := runs + trunc(mult);
  116.  
  117.       if not iopt then
  118.       begin
  119.          reads := reads + hex(44) * mult;
  120.          writes := writes + hex(49) * mult;
  121.          others := others + hex(54) * mult;
  122.       end;
  123.    end;
  124. end;
  125.  
  126.  
  127. {zero the current cmd totals}
  128. procedure initial_totals;
  129. begin
  130.    with cmd do
  131.    begin
  132.       name := copy(line,1,12);
  133.       time := 0;
  134.       reads := 0;
  135.       writes := 0;
  136.       others := 0;
  137.       runs := 0;
  138.    end;
  139. end;
  140.  
  141.  
  142. {display report titles based on -v and -i options}
  143. procedure write_titles;
  144. begin
  145.    if not vopt then
  146.    begin
  147.  
  148.       if not iopt then
  149.       begin
  150.          writeln('    Total    Average  -- Sys Call Averages --   ');
  151.          writeln('    Time      Time     Reads   Writes   Misc   Runs     Command');
  152.          writeln(' ---------- --------- ------- ------- ------- ------ --------------');
  153.       end
  154.       else
  155.  
  156.       begin
  157.          writeln('    Total    Average    ');
  158.          writeln('    Time      Time     Runs     Command');
  159.          writeln(' ---------- --------- ------ --------------');
  160.       end;
  161.    end;
  162. end;
  163.  
  164.  
  165. {output a line of totals based on -j and -i options; updates other totals
  166.  instead of producing output when runs=1}
  167. procedure write_totals;
  168.  
  169.    function timeformat(n: real): anystring;
  170.  
  171.       function number(n: real): anystring;
  172.       var
  173.          buf: anystring;
  174.       begin
  175.          while n > 10000.0 do
  176.             n := n - 10000;
  177.          str(trunc(n) mod 100:0,buf);
  178.          if length(buf) < 2 then
  179.             buf := '0' + buf;
  180.          number := buf;
  181.       end;
  182.  
  183.    begin
  184.       timeformat := number(n / 3600.0) + ':' +
  185.                     number(n / 60.0)   + ':' +
  186.                     number(n) + '.'    +
  187.                     number(n * 100);
  188.    end;
  189.  
  190.    function hexformat(n: real): anystring;
  191.  
  192.       function digit(n: real): anystring;
  193.       var
  194.          i: integer;
  195.       begin
  196.          while n > 16384.0 do
  197.             n := n - 16384.0;
  198.          i := trunc(n) and 15;
  199.          if i > 9 then
  200.             i := i + 7;
  201.          digit := chr(i + ord('0'));
  202.       end;
  203.  
  204.    begin
  205.       hexformat := digit(n / 4096.0) + digit(n / 256.0) +
  206.                    digit(n / 16.0)  +  digit(n);
  207.    end;
  208.  
  209. begin
  210.    with cmd do
  211.    begin
  212.       if jopt and (runs=1) then
  213.       begin
  214.          other.time := other.time + time;
  215.          other.reads := other.reads + reads;
  216.          other.writes := other.writes + writes;
  217.          other.others := other.others + others;
  218.          other.runs := other.runs + 1;
  219.       end
  220.       else
  221.  
  222.       if sopt then
  223.          writeln(name,' ',
  224.                  copy(line,14,18),
  225.                  timeformat(time/int(runs)),' ',
  226.                  hexformat(reads/int(runs)),' ',
  227.                  hexformat(writes/int(runs)),' ',
  228.                  hexformat(others/int(runs)),' ',
  229.                  runs)
  230.       else
  231.       if iopt then
  232.          writeln(time:10:1,' ',
  233.                  time/int(runs):9:2,' ',
  234.                  runs:6,'   ',
  235.                  name)
  236.       else
  237.          writeln(time:10:1,' ',
  238.                  time/int(runs):9:2,' ',
  239.                  reads/int(runs):7:0,' ',
  240.                  writes/int(runs):7:0,' ',
  241.                  others/int(runs):7:0,' ',
  242.                  runs:6,'   ',
  243.                  name);
  244.    end;
  245. end;
  246.  
  247.  
  248. {process command line options}
  249. procedure get_options;
  250. var
  251.    i:   integer;
  252.    opt: anystring;
  253.  
  254. begin
  255.    iopt := false;
  256.    jopt := false;
  257.    vopt := false;
  258.    sopt := false;
  259.  
  260.    for i := 1 to paramcount do
  261.    begin
  262.       opt := paramstr(i);
  263.  
  264.       if opt[1] in ['-','/'] then
  265.          delete(opt,1,1);
  266.  
  267.       case upcase(opt[1]) of
  268.  
  269.          'I':  iopt := true;
  270.  
  271.          'J':  jopt := true;
  272.  
  273.          'V':  vopt := true;
  274.  
  275.          'S':  begin
  276.                   sopt := true;
  277.                   iopt := false;
  278.                   jopt := false;
  279.                   vopt := true;
  280.                end;
  281.  
  282.          else
  283.             writeln(con);
  284.             writeln(con,'invald option: ',opt);
  285.             writeln(con);
  286.             writeln(con,'usage:    SAFMT <INFILE >OUTFILE [options]');
  287.             writeln(con);
  288.             writeln(con,'options:  -i    exclude i/o counts');
  289.             writeln(con,'          -v    exclude headings');
  290.             writeln(con,'          -j    combine commands run only once');
  291.             writeln(con,'          -s    produce SYSACT summary format');
  292.             writeln(con);
  293.             writeln(con,'INFILE must be a sorted SYSACT.LOG activity file');
  294.             halt;
  295.       end;
  296.    end;
  297.  
  298. end;
  299.  
  300.  
  301. {main program}
  302. begin
  303.    writeln(con,version);
  304.    get_options;
  305.  
  306.    write_titles;
  307.  
  308.    readln(line);
  309.    initial_totals;
  310.    other := cmd;
  311.    update_totals;
  312.  
  313.    {process each record in the system activity log}
  314.    while not eof do
  315.    begin
  316.       readln(line);
  317.  
  318.       {accumulate repeats on the current record}
  319.       if name = copy(line,1,12) then
  320.          update_totals
  321.       else
  322.       begin
  323.          {different record, output accumulators and start new current}
  324.          write_totals;
  325.          initial_totals;
  326.          update_totals;
  327.       end;
  328.    end;
  329.  
  330.    {output the last record}
  331.    write_totals;
  332.  
  333.    if jopt then
  334.    begin
  335.       jopt := false;
  336.       cmd := other;
  337.       name := '**others';
  338.       write_totals;
  339.    end;
  340.  
  341. end.
  342.  
  343.